home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / sgmllib.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  14KB  |  567 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import markupbase
  5. import re
  6. __all__ = [
  7.     'SGMLParser',
  8.     'SGMLParseError']
  9. interesting = re.compile('[&<]')
  10. incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|<([a-zA-Z][^<>]*|/([a-zA-Z][^<>]*)?|![^<>]*)?')
  11. entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
  12. charref = re.compile('&#([0-9]+)[^0-9]')
  13. starttagopen = re.compile('<[>a-zA-Z]')
  14. shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
  15. shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
  16. piclose = re.compile('>')
  17. endbracket = re.compile('[<>]')
  18. tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
  19. attrfind = re.compile('\\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\\s*=\\s*(\\\'[^\\\']*\\\'|"[^"]*"|[][\\-a-zA-Z0-9./,:;+*%?!&$\\(\\)_#=~\\\'"@]*))?')
  20.  
  21. class SGMLParseError(RuntimeError):
  22.     pass
  23.  
  24.  
  25. class SGMLParser(markupbase.ParserBase):
  26.     entity_or_charref = re.compile('&(?:([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+))(;?)')
  27.     
  28.     def __init__(self, verbose = 0):
  29.         self.verbose = verbose
  30.         self.reset()
  31.  
  32.     
  33.     def reset(self):
  34.         self._SGMLParser__starttag_text = None
  35.         self.rawdata = ''
  36.         self.stack = []
  37.         self.lasttag = '???'
  38.         self.nomoretags = 0
  39.         self.literal = 0
  40.         markupbase.ParserBase.reset(self)
  41.  
  42.     
  43.     def setnomoretags(self):
  44.         self.nomoretags = self.literal = 1
  45.  
  46.     
  47.     def setliteral(self, *args):
  48.         self.literal = 1
  49.  
  50.     
  51.     def feed(self, data):
  52.         self.rawdata = self.rawdata + data
  53.         self.goahead(0)
  54.  
  55.     
  56.     def close(self):
  57.         self.goahead(1)
  58.  
  59.     
  60.     def error(self, message):
  61.         raise SGMLParseError(message)
  62.  
  63.     
  64.     def goahead(self, end):
  65.         rawdata = self.rawdata
  66.         i = 0
  67.         n = len(rawdata)
  68.         while i < n:
  69.             if self.nomoretags:
  70.                 self.handle_data(rawdata[i:n])
  71.                 i = n
  72.                 break
  73.             
  74.             match = interesting.search(rawdata, i)
  75.             if match:
  76.                 j = match.start()
  77.             else:
  78.                 j = n
  79.             if i < j:
  80.                 self.handle_data(rawdata[i:j])
  81.             
  82.             i = j
  83.             if i == n:
  84.                 break
  85.             
  86.             if rawdata[i] == '<':
  87.                 if starttagopen.match(rawdata, i):
  88.                     if self.literal:
  89.                         self.handle_data(rawdata[i])
  90.                         i = i + 1
  91.                         continue
  92.                     
  93.                     k = self.parse_starttag(i)
  94.                     if k < 0:
  95.                         break
  96.                     
  97.                     i = k
  98.                     continue
  99.                 
  100.                 if rawdata.startswith('</', i):
  101.                     k = self.parse_endtag(i)
  102.                     if k < 0:
  103.                         break
  104.                     
  105.                     i = k
  106.                     self.literal = 0
  107.                     continue
  108.                 
  109.                 if self.literal:
  110.                     if n > i + 1:
  111.                         self.handle_data('<')
  112.                         i = i + 1
  113.                         continue
  114.                     break
  115.                     continue
  116.                 
  117.                 if rawdata.startswith('<!--', i):
  118.                     k = self.parse_comment(i)
  119.                     if k < 0:
  120.                         break
  121.                     
  122.                     i = k
  123.                     continue
  124.                 
  125.                 if rawdata.startswith('<?', i):
  126.                     k = self.parse_pi(i)
  127.                     if k < 0:
  128.                         break
  129.                     
  130.                     i = i + k
  131.                     continue
  132.                 
  133.                 if rawdata.startswith('<!', i):
  134.                     k = self.parse_declaration(i)
  135.                     if k < 0:
  136.                         break
  137.                     
  138.                     i = k
  139.                     continue
  140.                 
  141.             elif rawdata[i] == '&':
  142.                 if self.literal:
  143.                     self.handle_data(rawdata[i])
  144.                     i = i + 1
  145.                     continue
  146.                 
  147.                 match = charref.match(rawdata, i)
  148.                 if match:
  149.                     name = match.group(1)
  150.                     self.handle_charref(name)
  151.                     i = match.end(0)
  152.                     if rawdata[i - 1] != ';':
  153.                         i = i - 1
  154.                         continue
  155.                     continue
  156.                 
  157.                 match = entityref.match(rawdata, i)
  158.                 if match:
  159.                     name = match.group(1)
  160.                     self.handle_entityref(name)
  161.                     i = match.end(0)
  162.                     if rawdata[i - 1] != ';':
  163.                         i = i - 1
  164.                         continue
  165.                     continue
  166.                 
  167.             else:
  168.                 self.error('neither < nor & ??')
  169.             match = incomplete.match(rawdata, i)
  170.             if not match:
  171.                 self.handle_data(rawdata[i])
  172.                 i = i + 1
  173.                 continue
  174.             
  175.             j = match.end(0)
  176.             if j == n:
  177.                 break
  178.             
  179.             self.handle_data(rawdata[i:j])
  180.             i = j
  181.         if end and i < n:
  182.             self.handle_data(rawdata[i:n])
  183.             i = n
  184.         
  185.         self.rawdata = rawdata[i:]
  186.  
  187.     _decl_otherchars = '='
  188.     
  189.     def parse_pi(self, i):
  190.         rawdata = self.rawdata
  191.         if rawdata[i:i + 2] != '<?':
  192.             self.error('unexpected call to parse_pi()')
  193.         
  194.         match = piclose.search(rawdata, i + 2)
  195.         if not match:
  196.             return -1
  197.         
  198.         j = match.start(0)
  199.         self.handle_pi(rawdata[i + 2:j])
  200.         j = match.end(0)
  201.         return j - i
  202.  
  203.     
  204.     def get_starttag_text(self):
  205.         return self._SGMLParser__starttag_text
  206.  
  207.     
  208.     def parse_starttag(self, i):
  209.         self._SGMLParser__starttag_text = None
  210.         start_pos = i
  211.         rawdata = self.rawdata
  212.         if shorttagopen.match(rawdata, i):
  213.             match = shorttag.match(rawdata, i)
  214.             if not match:
  215.                 return -1
  216.             
  217.             (tag, data) = match.group(1, 2)
  218.             self._SGMLParser__starttag_text = '<%s/' % tag
  219.             tag = tag.lower()
  220.             k = match.end(0)
  221.             self.finish_shorttag(tag, data)
  222.             self._SGMLParser__starttag_text = rawdata[start_pos:match.end(1) + 1]
  223.             return k
  224.         
  225.         match = endbracket.search(rawdata, i + 1)
  226.         if not match:
  227.             return -1
  228.         
  229.         j = match.start(0)
  230.         attrs = []
  231.         if rawdata[i:i + 2] == '<>':
  232.             k = j
  233.             tag = self.lasttag
  234.         else:
  235.             match = tagfind.match(rawdata, i + 1)
  236.             if not match:
  237.                 self.error('unexpected call to parse_starttag')
  238.             
  239.             k = match.end(0)
  240.             tag = rawdata[i + 1:k].lower()
  241.             self.lasttag = tag
  242.         while k < j:
  243.             match = attrfind.match(rawdata, k)
  244.             if not match:
  245.                 break
  246.             
  247.             (attrname, rest, attrvalue) = match.group(1, 2, 3)
  248.             if not rest:
  249.                 attrvalue = attrname
  250.             elif "'" == "'":
  251.                 pass
  252.             elif not "'" == attrvalue[-1:]:
  253.                 if '"' == '"':
  254.                     pass
  255.                 elif '"' == attrvalue[-1:]:
  256.                     attrvalue = attrvalue[1:-1]
  257.                 
  258.             attrvalue = self.entity_or_charref.sub(self._convert_ref, attrvalue)
  259.             attrs.append((attrname.lower(), attrvalue))
  260.             k = match.end(0)
  261.             continue
  262.             attrvalue[:1]
  263.         if rawdata[j] == '>':
  264.             j = j + 1
  265.         
  266.         self._SGMLParser__starttag_text = rawdata[start_pos:j]
  267.         self.finish_starttag(tag, attrs)
  268.         return j
  269.  
  270.     
  271.     def _convert_ref(self, match):
  272.         if match.group(2):
  273.             if not self.convert_charref(match.group(2)):
  274.                 pass
  275.             return '&#%s%s' % match.groups()[1:]
  276.         elif match.group(3):
  277.             if not self.convert_entityref(match.group(1)):
  278.                 pass
  279.             return '&%s;' % match.group(1)
  280.         else:
  281.             return '&%s' % match.group(1)
  282.  
  283.     
  284.     def parse_endtag(self, i):
  285.         rawdata = self.rawdata
  286.         match = endbracket.search(rawdata, i + 1)
  287.         if not match:
  288.             return -1
  289.         
  290.         j = match.start(0)
  291.         tag = rawdata[i + 2:j].strip().lower()
  292.         if rawdata[j] == '>':
  293.             j = j + 1
  294.         
  295.         self.finish_endtag(tag)
  296.         return j
  297.  
  298.     
  299.     def finish_shorttag(self, tag, data):
  300.         self.finish_starttag(tag, [])
  301.         self.handle_data(data)
  302.         self.finish_endtag(tag)
  303.  
  304.     
  305.     def finish_starttag(self, tag, attrs):
  306.         
  307.         try:
  308.             method = getattr(self, 'start_' + tag)
  309.         except AttributeError:
  310.             
  311.             try:
  312.                 method = getattr(self, 'do_' + tag)
  313.             except AttributeError:
  314.                 self.unknown_starttag(tag, attrs)
  315.                 return -1
  316.  
  317.             self.handle_starttag(tag, method, attrs)
  318.             return 0
  319.  
  320.         self.stack.append(tag)
  321.         self.handle_starttag(tag, method, attrs)
  322.         return 1
  323.  
  324.     
  325.     def finish_endtag(self, tag):
  326.         if not tag:
  327.             found = len(self.stack) - 1
  328.             if found < 0:
  329.                 self.unknown_endtag(tag)
  330.                 return None
  331.             
  332.         elif tag not in self.stack:
  333.             
  334.             try:
  335.                 method = getattr(self, 'end_' + tag)
  336.             except AttributeError:
  337.                 self.unknown_endtag(tag)
  338.  
  339.             self.report_unbalanced(tag)
  340.             return None
  341.         
  342.         found = len(self.stack)
  343.         for i in range(found):
  344.             if self.stack[i] == tag:
  345.                 found = i
  346.                 continue
  347.         
  348.         while len(self.stack) > found:
  349.             tag = self.stack[-1]
  350.             
  351.             try:
  352.                 method = getattr(self, 'end_' + tag)
  353.             except AttributeError:
  354.                 method = None
  355.  
  356.             if method:
  357.                 self.handle_endtag(tag, method)
  358.             else:
  359.                 self.unknown_endtag(tag)
  360.             del self.stack[-1]
  361.  
  362.     
  363.     def handle_starttag(self, tag, method, attrs):
  364.         method(attrs)
  365.  
  366.     
  367.     def handle_endtag(self, tag, method):
  368.         method()
  369.  
  370.     
  371.     def report_unbalanced(self, tag):
  372.         if self.verbose:
  373.             print '*** Unbalanced </' + tag + '>'
  374.             print '*** Stack:', self.stack
  375.         
  376.  
  377.     
  378.     def convert_charref(self, name):
  379.         
  380.         try:
  381.             n = int(name)
  382.         except ValueError:
  383.             return None
  384.  
  385.         if n <= n:
  386.             pass
  387.         elif not n <= 255:
  388.             return None
  389.         
  390.         return self.convert_codepoint(n)
  391.  
  392.     
  393.     def convert_codepoint(self, codepoint):
  394.         return chr(codepoint)
  395.  
  396.     
  397.     def handle_charref(self, name):
  398.         replacement = self.convert_charref(name)
  399.         if replacement is None:
  400.             self.unknown_charref(name)
  401.         else:
  402.             self.handle_data(replacement)
  403.  
  404.     entitydefs = {
  405.         'lt': '<',
  406.         'gt': '>',
  407.         'amp': '&',
  408.         'quot': '"',
  409.         'apos': "'" }
  410.     
  411.     def convert_entityref(self, name):
  412.         table = self.entitydefs
  413.         if name in table:
  414.             return table[name]
  415.         else:
  416.             return None
  417.  
  418.     
  419.     def handle_entityref(self, name):
  420.         replacement = self.convert_entityref(name)
  421.         if replacement is None:
  422.             self.unknown_entityref(name)
  423.         else:
  424.             self.handle_data(self.convert_entityref(name))
  425.  
  426.     
  427.     def handle_data(self, data):
  428.         pass
  429.  
  430.     
  431.     def handle_comment(self, data):
  432.         pass
  433.  
  434.     
  435.     def handle_decl(self, decl):
  436.         pass
  437.  
  438.     
  439.     def handle_pi(self, data):
  440.         pass
  441.  
  442.     
  443.     def unknown_starttag(self, tag, attrs):
  444.         pass
  445.  
  446.     
  447.     def unknown_endtag(self, tag):
  448.         pass
  449.  
  450.     
  451.     def unknown_charref(self, ref):
  452.         pass
  453.  
  454.     
  455.     def unknown_entityref(self, ref):
  456.         pass
  457.  
  458.  
  459.  
  460. class TestSGMLParser(SGMLParser):
  461.     
  462.     def __init__(self, verbose = 0):
  463.         self.testdata = ''
  464.         SGMLParser.__init__(self, verbose)
  465.  
  466.     
  467.     def handle_data(self, data):
  468.         self.testdata = self.testdata + data
  469.         if len(repr(self.testdata)) >= 70:
  470.             self.flush()
  471.         
  472.  
  473.     
  474.     def flush(self):
  475.         data = self.testdata
  476.         if data:
  477.             self.testdata = ''
  478.             print 'data:', repr(data)
  479.         
  480.  
  481.     
  482.     def handle_comment(self, data):
  483.         self.flush()
  484.         r = repr(data)
  485.         if len(r) > 68:
  486.             r = r[:32] + '...' + r[-32:]
  487.         
  488.         print 'comment:', r
  489.  
  490.     
  491.     def unknown_starttag(self, tag, attrs):
  492.         self.flush()
  493.         if not attrs:
  494.             print 'start tag: <' + tag + '>'
  495.         else:
  496.             print 'start tag: <' + tag,
  497.             for name, value in attrs:
  498.                 print name + '=' + '"' + value + '"',
  499.             
  500.             print '>'
  501.  
  502.     
  503.     def unknown_endtag(self, tag):
  504.         self.flush()
  505.         print 'end tag: </' + tag + '>'
  506.  
  507.     
  508.     def unknown_entityref(self, ref):
  509.         self.flush()
  510.         print '*** unknown entity ref: &' + ref + ';'
  511.  
  512.     
  513.     def unknown_charref(self, ref):
  514.         self.flush()
  515.         print '*** unknown char ref: &#' + ref + ';'
  516.  
  517.     
  518.     def unknown_decl(self, data):
  519.         self.flush()
  520.         print '*** unknown decl: [' + data + ']'
  521.  
  522.     
  523.     def close(self):
  524.         SGMLParser.close(self)
  525.         self.flush()
  526.  
  527.  
  528.  
  529. def test(args = None):
  530.     import sys as sys
  531.     if args is None:
  532.         args = sys.argv[1:]
  533.     
  534.     if args and args[0] == '-s':
  535.         args = args[1:]
  536.         klass = SGMLParser
  537.     else:
  538.         klass = TestSGMLParser
  539.     if args:
  540.         file = args[0]
  541.     else:
  542.         file = 'test.html'
  543.     if file == '-':
  544.         f = sys.stdin
  545.     else:
  546.         
  547.         try:
  548.             f = open(file, 'r')
  549.         except IOError:
  550.             msg = None
  551.             print file, ':', msg
  552.             sys.exit(1)
  553.  
  554.     data = f.read()
  555.     if f is not sys.stdin:
  556.         f.close()
  557.     
  558.     x = klass()
  559.     for c in data:
  560.         x.feed(c)
  561.     
  562.     x.close()
  563.  
  564. if __name__ == '__main__':
  565.     test()
  566.  
  567.